package metricx

import (
	"time"

	promclient "github.com/prometheus/client_golang/prometheus"
	"go.opentelemetry.io/otel/exporters/prometheus"
	metricx "go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/sdk/metric"
	"go.opentelemetry.io/otel/sdk/resource"
)

type PeriodicReaderConfig struct {
	Interval int `json:"interval" toml:"interval"`
	Timeout  int `json:"timeout"  toml:"timeout"`
}

func (c PeriodicReaderConfig) NewReader(exporter metric.Exporter, opts ...metric.PeriodicReaderOption) metric.Reader {

	options := make([]metric.PeriodicReaderOption, 0, len(opts)+2)
	options = append(options,
		metric.WithInterval(time.Duration(c.Interval)*time.Second),
		metric.WithTimeout(time.Duration(c.Timeout)*time.Second),
	)
	return metric.NewPeriodicReader(exporter,
		append(options, opts...)...,
	)
}

type PrometheusReaderConfig struct {
	Namespace         string
	WithoutScopeInfo  bool
	WithoutTargetInfo bool
}

func (c PrometheusReaderConfig) NewReader(reg promclient.Registerer, opts ...prometheus.Option) (metric.Reader, error) {
	options := make([]prometheus.Option, 0, len(opts))
	options = append(options,
		prometheus.WithNamespace(c.Namespace),
		prometheus.WithRegisterer(reg),
	)
	if c.WithoutScopeInfo {
		options = append(options, prometheus.WithoutScopeInfo())
	}
	if c.WithoutTargetInfo {
		options = append(options, prometheus.WithoutTargetInfo())
	}
	return prometheus.New(append(options, opts...)...)
}

func NewProvider(
	reader metric.Reader,
	res *resource.Resource,
	opts ...metric.Option,
) metricx.MeterProvider {
	optx := make([]metric.Option, 0, len(opts)+2)
	optx = append(optx, metric.WithResource(res), metric.WithReader(reader))
	return metric.NewMeterProvider(
		append(optx, opts...)...,
	)
}
